{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Nhân ma trận và vector\n",
    "----"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Một số công thức đại số tuyến tính **hiện thị không đúng trên Github**. Bạn có thể xem bản chuẩn [ở đây](http://nbviewer.jupyter.org/github/bangoc123/learn-machine-learning-in-two-months/blob/master/numpy/linear-algebra/products.ipynb)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### I. Đại lượng vô hướng, Véc-tơ, Ma trận (Scalar, Vector, Matrix)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Chú ý:** Vector là ma trận một chiều"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](https://lh3.googleusercontent.com/Et77RGsc4KdMljEb9QCnBbBhL8m8xBVwx7X4bJYSt5pQd6zh9PhFnDe-hqp6c6b0V09-n9L5oNPpyyzzB05pL_YeiuyhTCo8epITTv5jMH_9l93FASR5hmYD5ewg3FtFFImEAZ7PCZmNmmy6biMu_tuxf_TNMID9KZ0VElGId9rmvCuLPZ1o_GlqjC_dKrNBj_ze6swlDXYUKA7nn60ALa81W7yFO5WlUBQAdLB0XcgfOiBDlgGAxTBr5A1I2dmRjRZHu2nXQE3_pWpzICbdOtHiwFc2XL7fnJCE_jYLFikLvVt9LRHHk3Jy4gdZWi27SW-IfvpKMh0rUpVFOHyntKIfvIRU6DOxqq2zkOc4MUSZyMEwOENB6w5M-1vfzXJXE03O--q0WXpxotIZ_Zz4gC2_n64NMQv-_rSXtD5LB5tEkYdBI2fIdU9rux1pXOQEWeVPyTWGCWPRMJfkQ2ewk4Qi-pU6Q6WXnLdZtzFANF03neD5P25uXfnCJGDyXR__fxjMD3UUom77YTHSVbv8ekgIwkc4JEthhfZixkjE1A-2yvNlkxEBq8pylKxL0XMhS0rCXFZop8X25Bx3Mtq_iz74u34faZLhR77M1pioZWTM7L5O5QLpgQGVZhiIiA3XpzQiGQfBxiMakhPmrZKvYXNxCGyvaJyq0wNxqtNO0FSo8JJ9LB3agRFVKA=w1920-h684-no)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ảnh từ [Math is fun](https://www.mathsisfun.com/algebra/scalar-vector-matrix.html)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### II. inner() (Tích vô hướng 2 vector)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Trả về tích vô hướng của 2 vector."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 1. Công thức"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### a. Điều kiện nhân"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2 vector phải cùng chiều với nhau"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### b. Công thức tổng quát"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](https://lh3.googleusercontent.com/0q6b8mbWci1Vv2afQyKXivLhTq2YBHXneEGejTKDQZ2veo5Lt8FjEWs7P9c1qC4ajfwbn3MWry2JV0dx9Eii71o2pWP7TVCyn65ICPEslXfAaqkQKevyPgHhu5XW8lD6-oAxkMCEFtv9p0Jc70XoQ7bAc3C_f4HKE-VI_EX_U7aPkO3tZ-gJLv3Vv3O-4JoWAau-akq5eKiYsFIYPP_H98AyCMB6Y44AjO-N_4rxb4HIdVfajBuULhEOX8HecCBvXHvk5g0Rrj_4VJZSVjokWnAfMYBzmcrQkOKMT2eKoB50zdmehKhzLF250eMdieVTydFbzWmZosMpxk19RXxoaQCjXUNNJZ6JNO1Bed5qmVhDc70gJPSR6QYKh4ehym9tg33QqRmlAyUz8gqvIo2jmFG-Ziu10T-MTk-UiImMK2a5JdLK6KG33gm9jctg-fyzzuz5ThoyBXxmsGiTg8m8hpS67EgCLKK-ZH7ocWQg4q6EwaRkHI7NdWJdl4boImWtvR6BQ_3IVu0tmI-rM8KEeDohHPzdBqvLUjGtD1NH6bky8kJqqjYi3Akc68oxkzJytWcz8z2p_Gzc4cnoOzhOzLO1gfxeAq-YhJdCRYFsqmlCo0y1Ql5i5dGmyyA_z4CXGgz3IzirBLeT0A_KWHeqhrLM7b7u2zCIlEnEJEHOHHOg96cXCYORbjtYmg=w779-h146-no)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ảnh từ [Wiki](https://en.wikipedia.org/wiki/Inner_product_space)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 2. Thực hành với Numpy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [],
   "source": [
    "A = np.array([1, 2, 3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "B = np.array([4, 5, 6])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "32"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.inner(A, B)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Kết quả chính bằng **1 * 4 + 2 * 5 + 3 * 6**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### III. dot() (Tích vô hướng 2 ma trận)\n",
    "Trả về tích vô hướng của 2 ma trận. \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 1. Công thức"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### a. Điều kiện nhân"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A là ma trận có chiều $ \\mathbf{A} \\in \\mathbb{R}^{m x n}$ và $ \\mathbf{B} \\in \\mathbb{R}^{n x p}$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Để phép nhân $\n",
    "\\mathbf{A}\\mathbf{B}\n",
    "$ thành công thì số **số cột của A** phải bằng **số dòng của B** (trong trường hợp này đều bằng **n**) và ngược lại."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### b. Dạng tổng quát"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](https://lh3.googleusercontent.com/SNC6JcFQX-OuuHuLsJf25pBD2VG2HuBMhJX5v4LHs8_GdV8gWG1_H2ut3nxtlXaBpI6Ca6_n3FwsvwAStoxcZaT4JVySP3yznxt7G2FXY2WyLO5DxeaaMhwso8tdpNEJJgIa5JTOsGYmmQ-mJzzrsa0oFZU6BmmNc8xiD7sIwRATnRa5rZ8v9_GLa73Kna4qo9LnuGhi0BbmCBZA5mPB1_qKtH9qg3OOlxNlgwFo_GNSRPuI-_biVv7Y3hoqPpvum5xRAa2OvW91tURF9ayG9q3vF9HgYl1P4cv1AbpIs1d66i-_2R2z6_lD3Tv7jWU3aa2Asgluo5X2cF7Y9Ri_HfaZVxAdjAi91I8dOuZxIh0tmcBhazINfb4m409XlvGRKvxkAenOlDHWCRWkqOdL7bdEu8VfXY_jNrravR8m3jo2v1V90JmKS58Sm1N_JbHU_tKylVxf_BTzmqijw-vJpNgszHjOKzYM8PT6KLKBuP0-GUSuY0GweKAVoqyvRYyrsWwxtP4nTPDo1r_PSFyKsZCNXiJTlAM3NJkCeFBM0ExKJtiXl3MJroy2HVKZ5bUBK6zAwqLGvJTeIAa69fPKdlglJwkfTnfk-P_srHGrzCOlpKIVQVB6YHGFnm9JjFJXLiFvHiXSDwI23kGFiK5pzAW059dS8obRX3y1_Jz7qtEa04QkkB1wHjKxAA=w750-h405-no)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ảnh chụp từ [Wiki](https://en.wikipedia.org/wiki/Matrix_multiplication)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Diễn giải ma trận kết quả c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Giá trị của vị trí dòng 1 cột 1 của c ($\\mathbf{c}_{11}$) là **tích có hướng** của **dòng 1 ma trận A** và **cột 1 ma trận B**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$$\n",
    "\\begin{equation}\n",
    "\\begin{array}{c}\n",
    "c_{11} = \\begin{vmatrix}\n",
    "\\mathbf{a}_{11} \\ \\mathbf{a}_{12} \\ \\mathbf{.} \\ \\mathbf{.} \\ \\mathbf{a}_{1m}\n",
    "\\end{vmatrix} \\begin{vmatrix} \n",
    "\\mathbf{b}_{11} \\\\ \\mathbf{b}_{21} \\\\. \\\\. \\\\ \\mathbf{b}_{m1}\n",
    "\\end{vmatrix}\n",
    "= \\mathbf{a}_{11}\\mathbf{b}_{11} + \\mathbf{a}_{12}\\mathbf{b}_{21} + .. + \\mathbf{a}_{1m}\\mathbf{b}_{m1}\n",
    "\\end{array}\n",
    "\\end{equation}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Giá trị của vị trí dòng 1 cột 2 của c ($\\mathbf{c}_{12}$) là **tích có hướng** của **dòng 1 ma trận A** và **cột 2 ma trận B**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$$\n",
    "\\begin{equation}\n",
    "\\begin{array}{c}\n",
    "c_{12} = \\begin{vmatrix}\n",
    "\\mathbf{a}_{11} \\ \\mathbf{a}_{12} \\ \\mathbf{.} \\ \\mathbf{.} \\ \\mathbf{a}_{1m}\n",
    "\\end{vmatrix} \\begin{vmatrix} \n",
    "\\mathbf{b}_{12} \\\\ \\mathbf{b}_{22} \\\\. \\\\. \\\\ \\mathbf{b}_{m2}\n",
    "\\end{vmatrix}\n",
    "= \\mathbf{a}_{11}\\mathbf{b}_{12} + \\mathbf{a}_{12}\\mathbf{b}_{22} + .. + \\mathbf{a}_{1m}\\mathbf{b}_{m2}\n",
    "\\end{array}\n",
    "\\end{equation}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tương tự với bất kỳ vị trí nào"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Giá trị của vị trí dòng n cột p của c ($\\mathbf{c}_{np}$) là **tích có hướng** của **dòng n ma trận A** và **cột p ma trận B**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$$\n",
    "\\begin{equation}\n",
    "\\begin{array}{c}\n",
    "c_{np} = \\begin{vmatrix}\n",
    "\\mathbf{a}_{n1} \\ \\mathbf{a}_{n2} \\ \\mathbf{.} \\ \\mathbf{.} \\ \\mathbf{a}_{nm}\n",
    "\\end{vmatrix} \\begin{vmatrix} \n",
    "\\mathbf{b}_{1p} \\\\ \\mathbf{b}_{2p} \\\\. \\\\. \\\\ \\mathbf{b}_{mp}\n",
    "\\end{vmatrix}\n",
    "= \\mathbf{a}_{n1}\\mathbf{b}_{1p} + \\mathbf{a}_{n2}\\mathbf{b}_{2p} + .. + \\mathbf{a}_{nm}\\mathbf{b}_{mp}\n",
    "\\end{array}\n",
    "\\end{equation}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### c. Dạng mô phỏng\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](https://lh3.googleusercontent.com/vMoe14bFuc3omi9CHuGppJwGDNFdyXwcBbLnCwk-Wfz9lESrkM3hgBjL-L4Xwp81zFP8GjkFbnI94ofzMB0ejzyjSVKkJ8rKaxTZUYpOU6CEYTTTHqjQRa6OgKbovfppjhaG5TN40wPuT-xETWHJoSTCV5UKYb4bnD9dX292ed8zexAltH2MZgO984l6xovIs549xzyuWNeize2q3qcn5Foq6_jGf0Jw6b2DM1yJA1HfDUzfzJMy8umC901BmuWn5HHGBSFFbjdYNTnoTQYcyEVMXtqK89PQPWHbNoOmILmNAbBEXHr02zVggIJyxULtU48HsN-98UnxQ6VJFcouJ-L7uNxdWIM89STI92Sur2KfIh_Ueguv_2c9-Iccjin07LdetsR5GtQebd0Q0pLqHrfuMvJVTJXlDpF09T5nGtquP134ZHfzC1j1Y80uEghMxxWUAIFkONXei8TX8uwq_EkOmOcLWAhtIBNmlCmFulru9YAPCUXF4z2qJHTK9o_FnQ5Z0cQyfloX3IbLrvtoCjrpEgJ-A7XWiZTv1_A0Aan7jMER4E5ziIEamJL3B9HJ8GBgLizy4AKZOnue3L7dTr6BbqG19A53OmMHtjlUWjMaMmtq8F_HnQL2HIuizZ__IqwCkgXVsE8pB-scQEFBB82qv02qyJ0zwcBTx6iTaIUrN6Qz6k43q_Vo4Q=w369-h209-no)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ảnh chụp từ [Wiki](https://en.wikipedia.org/wiki/Matrix_multiplication)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 2. Thực hành với Numpy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "A = np.array([\n",
    "    [1, 2],\n",
    "    [3, 4]\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "B = np.array([\n",
    "    [5, 6],\n",
    "    [7, 8]\n",
    "])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### a. Tích vô hướng của a và b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[19, 22],\n",
       "       [43, 50]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A.dot(B)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tương đương với"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[19, 22],\n",
       "       [43, 50]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.dot(A, B)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### b. Tích vô hướng của b và a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[23, 34],\n",
       "       [31, 46]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "B.dot(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[23, 34],\n",
       "       [31, 46]])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.dot(B, A)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Chú ý:** Phép nhân ma trận không có tính chất giao hoán."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$$\n",
    "\\mathbf{A}\\mathbf{B} \\neq \\mathbf{B}\\mathbf{A}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### IV. tensordot()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 1. Công thức"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### a. Dạng tổng quát"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](https://lh3.googleusercontent.com/kp6Et_pqBJoQCVVoHV4v6cZsTeUqh9S2Bx-g6qpdgWF7Wt_cbsCRL9yO8seJhQZguhBJ2SE7mKJUzIuU7rrlyxvArYsKe1898T_LVpjnEznwSsLUiXY9RmTNct0jlHVrEPn-A-qaIF-Un0SbFfkMsYv6kJ_YCxCtpCgRokRXmWK4TSGLVFVh6MEqZ9LgWSK8xIBEWKaxrU3aTYY98kRQFYPluX5wL92g-qyiPZdraUwjS-E1N2ugSHVuEXLf2Zpz60GP-CC0ZQ9pFnNRdcG-0FAudFQsknLBNP22po0hfJTifAv5N1x5Bqu2p9xYmzlGsFOFEXrh34qIRMu008Xlcb6QndpykUXzoATv9gJAURXl7-HrqIZLz4-cMOW4XO5eTgLSIv_46RhLryVybLPqgmQdlG_5a2uWc9LCqeGEFRwfRtDaADwbNHO2cHgspKt2BvX1tas0F74VNj2UBpITLwgt-MXv9RHjiWVGE7FhJ7Dg82CxkmGzpzoDXLmVJ1hJfwaC4iDOPlOi-0WJZUGeQZ-AcGrr13ydie_sCcoPpYlFa6v2D9CS9J1NW_XNy-T0KVlExappXb6Tx4FGUjTAQGNtwzVlLk8zlD4QhmYlwJ8yAJ-WqM1gj6AYZDJZUr0HWersfI2zZMSNMjxeQu9r_4tZtJcN0Gx5FMpFFeipjo1tHRcGPO6eDcNKEg=w608-h367-no)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### b. Dạng mô phỏng"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](https://lh3.googleusercontent.com/U431n_zl35riy-ksezQNi99oJa-5Qr9wwsgddAa0KT2QrpLsVmAp9en6DHloiJUOAXJHBMkoYC0l6PHHYcgbaGKUHdMuS8P8SKBhc9TydoVda7n9fuc-w96km_t_j-Den-q6tXo3skKtvIwuHXX9o_wyfQbMuc3wK9JNNHpKXm2TTm8Qa301Xl70_aXUmmD9t07-o3bLVSZi782NcMZ3l8OY8wEt_Tjv4NQ-y039xD_anKk6OuJFCuQOcKGQzQL9k_RfYrFIqa_kVyXahFmLSOfWshXgkhIfxYorz9iUFe_9nKlichPwIzuJfzrGPHYkrYYC3vN8A1HMXYTjYykyurg28gla1A_5bBcu89B45QXLkuov8kpBxspjYxXIyCmdBEqYYW4ZR1LKDa3BN_RIykKZllJGcKr74G6eP4NMAMQimNf3dIYkSGCTjr99h3tGz0sdtHPtM7EdtM8fnllT4-vhAJkw9_EQPqsB59uDYqVSk7Q8ozAYm9QNC3ttCgMQUK-SMkKFwi9tpyyY8kftkMLaxx9mCPfFIW8qV8D7VPG2pH7YLpky8-27KR8PjLF6yDbpIlhnMWV5CNCeQZM2UrWltdodBq836EM30UagEJOBS99F39qYUb0yWfaU5vY-A83-WpD1NRFrYVvfxVsenvqzywVLUreytiqYZpeVgzoKNy1NYRlmueG90g=w551-h186-no)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 2. Thực hành với Numpy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [],
   "source": [
    "A = np.array([\n",
    "    [2, 0, 6],\n",
    "    [1, -1, 2],\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "B = np.array([\n",
    "    [8, -3, 2],\n",
    "    [4, 1, -5],\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(21)"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.tensordot(A, B)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
